package com.neuedu.config;

import com.auth0.jwt.JWT;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.neuedu.service.IBackPermissionService;
import com.neuedu.service.IPermissionService;
import com.neuedu.service.IRedisService;
import com.neuedu.util.CommonResult;
import com.neuedu.util.JWTUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

@Component
public class MyWebInterceptor extends HandlerInterceptorAdapter {
    @Resource
    IRedisService redisService;
    @Resource
    IPermissionService permissionService;
    @Resource
    IBackPermissionService backPermissionService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("进入拦截器");
        String uri = request.getRequestURI();
        String method = request.getMethod();
        String token = request.getHeader("token");
        System.out.printf("uri:%s\nmethod:%s\ntoken:%s\r\n", uri, method, token);
        //如果没有token 或者ssdb中用户不存在 //notoken
        if (StringUtils.isBlank(token)) {
            writeMsg(response, CommonResult.notoken());
            return false;
        }

        //获取ssdb中的密码跟token中的密码不一致 //notoken
        String username = JWT.decode(token).getClaim("username").asString();
        Integer userId = JWT.decode(token).getClaim("id").asInt();
        String key = JWTUtil.KEY + "-" + username;
        if (redisService.hasKey(key)) {
            String password = JWT.decode(token).getClaim("password").asString();
            Long timestamp = JWT.decode(token).getClaim("timestamp").asLong();
            String userJson = redisService.get(key);
            ObjectMapper objectMapper = new ObjectMapper();
            Map userMap = objectMapper.readValue(userJson, Map.class);
            /*System.out.println("password:" + password);
            System.out.println("timestamp:" + timestamp);
            System.out.println("map p:" + userMap.get("password"));
            System.out.println("map t:" + userMap.get("lastLogin"));*/
            if (!password.equals(userMap.get("password")) || timestamp.longValue() != (long) userMap.get("lastLogin")) {
                writeMsg(response, CommonResult.notoken());
                return false;
            }
            redisService.expire(key, 30 * 60);
        } else {
            writeMsg(response, CommonResult.notoken());
            return false;
        }

        //没有权限 //nopermiss
        if (!validateUriPermission(username,userId, uri)) {
            writeMsg(response, CommonResult.nopremiss());
            return false;
        }

        return true;
    }

    private void writeMsg(HttpServletResponse response, CommonResult result) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");

        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(result);
        PrintWriter out = response.getWriter();
        out.write(json);
        out.flush();
        out.close();
    }

    private boolean validateUriPermission(String username,Integer userId, String uri) throws IOException {
        //查询权限列表
        List<String> umsPermissionList = null;

        //从ssdb缓存数据库中获取当前用户的权限列表

        //
        ObjectMapper objectMapper = new ObjectMapper();
        String json = redisService.get(JWTUtil.PERMISSION_KEY+"_"+username);
        if(StringUtils.isBlank(json)){
            //从数据库中获取权限列表
            umsPermissionList = backPermissionService.userPermissionListValidate(userId);
            //并序列化成json，放到ssdb中

            json = objectMapper.writeValueAsString(umsPermissionList);
            redisService.set(JWTUtil.PERMISSION_KEY+"_"+username,json,30*60);

        }else{
            JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class,String.class);
            umsPermissionList = objectMapper.readValue(json,javaType);

        }

        for (String permission : umsPermissionList) {
            if(uri.equals(permission)){
                return true;
            }
        }
        return false;
    }
}
